package com.suxin.web;

import com.suxin.domain.User;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.context.request.async.DeferredResult;

import javax.servlet.AsyncContext;
import javax.servlet.AsyncEvent;
import javax.servlet.AsyncListener;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * @author Tang
 * @classname TestController
 * @description [  ]
 * @date 2022/7/22 10:52
 */
@Slf4j
@RestController
@RequestMapping("/test")
public class TestController {

    private final static Map<String, AsyncContext> clientMap = new HashMap<>(8);

    @GetMapping("/start")
    public void startAsync(HttpServletRequest request, HttpServletResponse response) {
        AsyncContext asyncContext = clientMap.get(request.getParameter("id"));
        asyncContext.start(() -> {
            for (int i = 0; i < 3; i++) {
                //模拟业务请求
                try {
                    Thread.sleep(1000);
                    asyncContext.getResponse().getWriter().println("hello world" + i + "\n");
                } catch (Exception e) {
                    throw new RuntimeException(e);
                }
            }
            System.out.println("complete执行完毕");
            asyncContext.complete();
        });
    }

    @GetMapping("/async")
    public void registerAsync(HttpServletRequest request, HttpServletResponse response) {
        response.setContentType("text/html;charset=UTF-8");
        AsyncContext asyncContext = request.startAsync(request, response);
        asyncContext.setTimeout(10000);
        asyncContext.addListener(new AsyncListener() {
            @Override
            public void onComplete(AsyncEvent event) throws IOException {
                System.out.println(event);
                System.out.println("onComplete...");
            }

            @Override
            public void onTimeout(AsyncEvent event) throws IOException {
            }

            @Override
            public void onError(AsyncEvent event) throws IOException {
            }

            @Override
            public void onStartAsync(AsyncEvent event) throws IOException {
                System.out.println("onStartAsync...");
            }
        });
        clientMap.put(request.getParameter("id"), asyncContext);
    }

    @GetMapping("/mergerResult")
    public User mergerResult() {
        Request<User, UserQuery> request = new Request<>();
        request.setTimeOut(4000);
        request.init();
        try {
            return request.getFuture().get(request.getTimeOut(),TimeUnit.MILLISECONDS);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return new User();
    }

    @GetMapping("/test/deferredResult")
    public DeferredResult<User> asyncDeferredResult() {
        DeferredResult<User> deferredResult = new DeferredResult<>(10000L);

        deferredResult.onError((throwable) -> {
            System.out.println("异常发生了！");
        });

        deferredResult.onCompletion(() -> {
            System.out.println("结果出来了！");
        });

        deferredResult.onTimeout(() -> {
            System.out.println("超时了！");
        });
        new Thread(() -> {
            try {
                System.out.println("睡眠8s开始....");
                TimeUnit.SECONDS.sleep(8);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("睡眠结束,结果返回....");
            // 处理数据
            deferredResult.setResult(new User());
        }).start();
        return deferredResult;
    }
}